Overview
Yew is a modern Rust framework inspired by Elm and React for creating multi-threaded frontend apps with WebAssembly.
The framework supports multi-threading & concurrency out of the box. It uses Web Workers API to spawn actors (agents) in separate threads and uses a local scheduler attached to a thread for concurrent tasks.
Check out a live demo powered by yew-wasm-pack-template
Cutting Edge technologies
Rust to WASM compilation
This framework is designed to be compiled into modern browsers' runtimes: wasm, asm.js, emscripten.
Architecture inspired by Elm and Redux
Yew implements strict application state management based on message passing and updates:
src/main.rs
use ;
Predictable mutability and lifetimes (thanks Rust!) make it possible to reuse a single instance of the model without a need to create a fresh one on every update. It also helps to reduce memory allocations.
JSX-like templates with html!
macro
Feel free to put pure Rust code into HTML tags with all the compiler and borrow checker's benefits.
html!
Agents - actor model inspired by Erlang and Actix
Every Component
can spawn an agent and attach to it.
Agents can coordinate global state, spawn long-running tasks, and offload tasks to a web worker.
They run independently of components, but hook nicely into their update mechanism.
use *;
Build the bridge to an instance of this agent. It spawns a worker automatically or reuses an existing one, depending on the type of the agent:
You can use as many agents as you want. For example you could separate all interactions with a server to a separate thread (a real OS thread because Web Workers map to the native threads).
REMEMBER! Not every API is available for every environment. For example you can't use
StorageService
from a separate thread. It won't work withPublic
orPrivate
agents, only withJob
andContext
ones.
Components
Yew supports components! You could create a new one by implementing a Component
trait
and including it directly into the html!
template:
html!
Scopes
Components live in an Angular-like scopes with parent-to-child (properties) and child-to-parent (events) interaction.
Properties are also pure Rust types with strict type-checking during the compilation.
// my_button.rs
// confirm_dialog.rs
html!
Fragments
Yew supports fragments: elements without a parent which can be attached to one somewhere else.
html!
Virtual DOM
Yew uses its own virtual-dom implementation. It updates the browser's DOM with tiny patches when properties of elements have changed. Every component can be interacted with using its (Scope
) to pass messages and trigger updates.
The ShouldRender
returns the value which informs the loop when the component should be re-rendered:
Using ShouldRender
is more effective than comparing the model after every update because not every change to the model
causes an update to the view. It allows the framework to only compare parts of the model essential to rendering the view.
Rust/JS/C-style comments in templates
Use single-line or multi-line Rust comments inside html-templates.
html!
Third-party crates and pure Rust expressions inside
Use external crates and put values from them into the template:
extern crate chrono;
use *;
Some crates don't support the
wasm32-unknown-unknown
target yet.
Services
Yew has implemented pluggable services that allow you to call external APIs, such as: JavaScript alerts, timeout, storage, fetches and websockets. It's a handy alternative to subscriptions.
Implemented:
IntervalService
RenderService
ResizeService
TimeoutService
StorageService
DialogService
ConsoleService
FetchService
WebSocketService
KeyboardService
use ;
Can't find an essential service? Want to use a library from npm
?
You can wrap JavaScript
libraries using stdweb
and create
your own service implementation. Here's an example below of how to wrap the
ccxt library:
;
Easy-to-use data conversion and destructuring
Yew allows for serialization (store/send and restore/receive) formats.
Implemented: JSON
, TOML
, YAML
, MSGPACK
, CBOR
.
In development: BSON
, XML
.
use Json;
Only JSON
is available by default but you can activate the rest through features in
your project's Cargo.toml
:
[]
= { = "https://github.com/yewstack/yew", = ["toml", "yaml", "msgpack", "cbor"] }
Development setup
Clone or download this repository.
Install cargo-web
This is an optional tool that simplifies deploying web applications:
Add
--force
option to ensure you install the latest version.
Build
# without cargo-web, only the wasm32-unknown-unknown target is supported
Running Tests
For the tests to work one have to ensure that wasm-bindgen-cli
is installed.
Instructions
Additionally a webdriver must be installed locally and configured to be on the
PATH
. Currently supports geckodriver
, chromedriver
, and safaridriver
,
although more driver support may be added! You can download these at:
- geckodriver - https://github.com/mozilla/geckodriver/releases
- chromedriver - http://chromedriver.chromium.org/downloads
- safaridriver - should be preinstalled on OSX
Running the examples
There are many examples that show how the framework works: counter, crm, custom_components, dashboard, fragments, game_of_life, mount_point, npm_and_rest, timer, todomvc, two_apps.
To start an example enter its directory and start it with cargo-web:
To run an optimised build instead of a debug build use:
This will use the wasm32-unknown-unknown
target by default, which is Rust's native WebAssembly target.
The Emscripten-based wasm32-unknown-emscripten
and asmjs-unknown-emscripten
targets are also supported
if you tell the cargo-web
to build for them using the --target
parameter.